Jx.categorize('platform.browser.detection', {

	$extend: 'Jx.lib.Detect',

	$accessors: {

		secured: false,

		strict: false,

		engine: 'Unknown',

		engineVersion: '0',

		os: 'Unknown',

		osVersion: '0',

		platform: 'Unknown',

		devicePlatform: 'Unknown',

		borderBox: true,

		quirksMode: false

	},

	$inherit: [ 'compareCallbacks', 'ignoreTokenLookup', 'versionReferences' ],

	compareCallbacks: {

		'engineVersion': function(baseValue, operator, token){

			return this.$Number.compare(operator, baseValue, token);

		},

		'osVersion': function(baseValue, operator, token){

			return this.$Number.compare(operator, baseValue, token);

		}

	},

	versionReferences: {

		'engine': 'engineVersion',

		'os': 'osVersion'

	},

	userAgent: null,

	versionRe: /[0-9]+(\.[0-9]+)?/,

	browsers: {

		'IE': 'MSIE ',

		'Firefox': 'Firefox/',

		'Chrome': 'Chrome/',

		'Safari': 'Version/',

		'Opera': 'Opera/'

	},

	engines: {

		'Webkit': 'AppleWebKit/',

		'Gecko': 'Gecko/',

		'Presto': 'Presto/',

		'Trident': 'Trident/'

	},

	oss: {

		'iOS': 'iPhone OS ',

		'Android': 'Android ',

		'WebOS': 'webOS/ ',

		'BlackBerry': 'BlackBerry ',

		'MacOSX': /mac/i,

		'Windows' : /win/i,

		'Linux' : /linux/i

   },

	platforms: {

		'iPhone': 'platform',

		'iPod': 'platform',

		'iPad': 'userAgent',

		'Mac': 'platform'

	},

	constructor: function(){

		var GLOBAL = Jx.GLOBAL;

		this.capable( 'window' in GLOBAL && GLOBAL['window'] == GLOBAL );

		this.userAgent = this.capable() ?

			GLOBAL.navigator.userAgent

			:

			'';

		this.$super();

	},

	initTokenLookup: function(cache, lookup){

		this.$super(arguments);


	},

	onAfterDetect: function(){

		var N = this.$Number,

			strict, version;

		if (this.name() == 'IE'){

			strict = this.strict();

			version = this.version();

			//-- apply
			this.borderBox(

				!(strict && N.compare('<=', version, 7))

			);

			//-- check quirksMode
			this.quirksMode( !strict );

		}

		this.$super(arguments);

	},

/**
 * DOM Browser Setup
 */
	onSetup: function(operation, platform){



	},

/**
 *	Browser Detection
 */

	//-- applies to name and version
	detectName: function(){

		Jx.each(this.browsers, function(browser, prefix){

			var my = this,

				ua = my.userAgent,

				index = ua.indexOf(prefix),

				m, ret;

			if (index != -1){

				ret = false;

				my.name(browser);

				//-- get version
				m = ua.substring(index + prefix.length, ua.length).match( my.versionRe );

				if (m){

					my.version(m[0]);

				}

			}

		}, this);

		return this.name();

	},

	detectEngine: function(){

		Jx.each(this.engines, function(engine, prefix){

			var my = this,

				ua = my.userAgent,

				index = ua.indexOf(prefix),

				ret, m;

			if (index != -1){

				ret = false;

				my.engine(engine);

				//-- get version
				m = ua.substring(index + prefix.length, ua.length).match( my.versionRe );

				if (m){

					my.engineVersion( m[0] );

				}

			}

			return ret;

		}, this);

		return this.engine();

	},

	detectSecured: function(){

		return  (/^[a-z0-9]+s/i).test(location.protocol);

	},

	detectStrict: function(){

		return document.compatMode === "CSS1Compat";

	},

	detectOs: function(){

		Jx.each(this.oss, function(os, prefix){

			var my = this,

				ua = my.userAgent,

				vRe = my.versionRe,

				index = -1,

				m, tryNext;

			//-- prefix match
			if (Jx.isString(prefix)){

				index = ua.indexOf(prefix);

			//-- regex
			} else if (Jx.isRegExp(prefix) &&

				(m = ua.match(prefix))

			){

				index = ua.indexOf( prefix = m[0] );

			}

			tryNext = index == -1;

			if (!tryNext){

				my.os(os);

				if (!my.isSet('device')){

					my.devicePlatform(os);

				}

				//-- get version
				m = os == 'BlackBerry' ?

					ua.substring(ua.indexOf('Version/') + 8, ua.length).match(vRe)

					:

					ua.substring(index + prefix.length, ua.length).match(vRe);

				if (m){

					my.osVersion( m[0] );

				}


			}

			return tryNext;

		}, this);

		return this.os();

	},

	detectPlatform: function(){

		//-- set initial platform
		return Jx.GLOBAL.navigator.platform;

	},

	detectDevicePlatform: function(){

		Jx.each( this.platforms, function(platform, locate){

			var nil, ret,

				my = this,

				o = Jx.GLOBAL.navigator,

				nav = locate in o ?

					o[locate]

					:

					nil;

			if (nav && nav.indexOf(platform) != -1){

				my.devicePlatform(platform);

				ret = false;

			}

			return ret;

		}, this);

		return this.devicePlatform();

	}




});
